/**
 * Copyright (C) 2011 Audit Logger Project. All rights reserved.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.auditlogger.security;

import org.auditlogger.api.InternalException;
import org.auditlogger.config.ConfigurationServices;
import org.auditlogger.config.spi.PropertiesConfigurator;
import org.auditlogger.config.util.ConfigurationException;

public class SecurityService {
	
	private static PropertiesConfigurator config = null;
	
	static {
		try {
			config = ConfigurationServices.getPropertiesConfigurator();
		} catch (ConfigurationException e) {
			throw new InternalException (e.getMessage(), e);
		}
	}
	
	private static String beginMarker = config.startIndicator() + config.delimiter();
	private static String endMarker = config.delimiter() + config.endIndicator();
	
	private static EncryptorDecryptor encryptor = EncryptorDecryptor.getInstance();
	
	
	public static String secureLogMessage(String formattedMessage) {
		StringBuilder builder = new StringBuilder();
		builder.append("START"+ config.delimiter());
		
		String encyrptedMessage = encryptor.encrypt(formattedMessage);
		builder.append(encyrptedMessage);
		builder.append(config.delimiter());
		
		// String digestedMessage = Digester.digest(formattedMessage);
		String signature = Signer.sign(formattedMessage);
		builder.append(signature);
		builder.append(config.delimiter() + "END");
		return builder.toString();
		
	}
	
	public static String processSecuredLogMessage(String protectedMessage) 
	             throws EncryptionException, ConfigurationException, SignatureUnverifiableException {
		String encodedEncryptedMessage = getEncryptedMessage(protectedMessage);
		String result = encryptor.decrypt(encodedEncryptedMessage);
		String encodedSignature = getSignature(protectedMessage);
		boolean isSignatureVerified = SignatureVerifier.verify(encodedSignature, result);
		if (isSignatureVerified) {
			return result;
		} else {
			throw new SignatureUnverifiableException("Could not verify signature" + result);
		}
	}
	
	private static String removeStartAndEndMarkers(String protectedMessage) {
		String result = protectedMessage.substring(
				beginMarker.length(), (protectedMessage.length()-endMarker.length()));
		return result;
	}
	
	private static String[] getTokens (String protectedMessage) {
		String demarkedMessage = removeStartAndEndMarkers(protectedMessage);
		String[] splits = demarkedMessage.split(config.delimiter());
		assert splits.length == 2;
		return splits;
	}
	
	private static String getEncryptedMessage(String protectedMessage) {
		validate(protectedMessage);
		String result = getTokens(protectedMessage)[0];
		assert result != null && !result.trim().equals("");
		return result;
	}
	
	private static void validate(String protectedMessage) {
		assert protectedMessage != null 
	     && !protectedMessage.trim().equals(""): "input cannot be null or empty";
		assert protectedMessage.startsWith(beginMarker): "illegal format";
		assert protectedMessage.endsWith(endMarker): "illegal format";
	}
	
	private static String getSignature(String protectedMessage) {
		validate(protectedMessage);
		String result = getTokens(protectedMessage)[1];
		assert result != null && !result.trim().equals("");
		return result;
	}
	
	public static void main (String[] args) 
	     throws EncryptionException, ConfigurationException, SignatureUnverifiableException {
		String protectedMessage = "START----+8ECpunTXHQ18pltWGEF6cT64K9vQHa/TSFGc2q1+mil7lNU2TTVkULQqezxKXBsTZ1L+3WgApvNFtIEwzjVhRnmtzqRc46N----MCwCFFyKLZ7BBeiNciJONTiT6uav+hXeAhQNVc93LBr6FEwC2SOEoh+d0nDOzQ==----END";
		/*String encodedEncryptedMessage = getEncryptedMessage(protectedMessage);
		System.out.println(encodedEncryptedMessage);
		String encodedSignature = getSignature(protectedMessage);
		System.out.println(encodedSignature);*/
		
		//String protectedMessage = "+8ECpunTXHQ18pltWGEF6cT64K9vQHa/TSFGc2q1+mil7lNU2TTVkULQqezxKXBsTZ1L+3WgApvNFtIEwzjVhRnmtzqRc46N";
		System.out.println(SecurityService.processSecuredLogMessage(protectedMessage));
	}

}
